﻿/************************************\
 *   ___                            *
 *  /                          /    *
 * (___ |  ___  ___       ___ (___  *
 * |    | |   )|___)| / )|___)|   ) *
 * |    | |    |__  |/|/ |__  |__/  *
 *                                  *
 * FireWeb    C# OpenSource Browser *
\************************************/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using Microsoft.WindowsAPICodePack.Taskbar;
using System.Resources;
using System.Globalization;
using System.Reflection;

namespace FireWeb
{
    public partial class App : Form
    {
        private Pipe.Server Server = new Pipe.Server();
        private string PipeName;
        private ResourceManager LangManager;
        private CultureInfo Culture;

        // Windows 7
        private TaskbarManager windowsTaskbar = TaskbarManager.Instance;
        private DWM.MARGINS Margins;

        private List<string> CompleteTitle = new List<string>();

        public App()
        {
            /*-5; 0
            669; 363*/
            InitializeComponent();

            // Language Loading
            Culture = new CultureInfo(Properties.Settings.Default.Language);
            LangManager = new ResourceManager("FireWeb.Languages.Resources", Assembly.GetExecutingAssembly());

            /*if (DWM.DwmIsCompositionEnabled())
            {
                Margins = new DWM.MARGINS();
                Margins.Top = 28;
                Margins.Left = 0;
                Margins.Right = 0;
                Margins.Bottom = 0;
                DWM.DwmExtendFrameIntoClientArea(this.Handle, ref Margins);

                DWM.WTA_OPTIONS ops = new DWM.WTA_OPTIONS();
                ops.Flags = DWM.WTNCA_NODRAWCAPTION | DWM.WTNCA_NODRAWICON;
                ops.Mask = DWM.WTNCA_NODRAWCAPTION | DWM.WTNCA_NODRAWICON;
                DWM.SetWindowThemeAttribute(this.Handle,
                    DWM.WindowThemeAttributeType.WTA_NONCLIENT,
                    ref ops,
                    (uint)Marshal.SizeOf(typeof(DWM.WTA_OPTIONS))
                );
            }*/

            // Pipe Server
            Server.MessageReceived += Server_ProcessPacket;
            Server.ClientDisconnected += Server_ClientDisconnected;

            if (!Server.Running)
            {
                Random Rnd = new Random();
                PipeName = @"\\.\pipe\FireWeb" + Rnd.Next();
                Server.Start(PipeName);
            }
        }

        #region AddNewTab Voids
        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

        [DllImport("user32.dll")]
        private static extern bool MoveWindow(IntPtr hwnd, int x, int y, int w, int h, bool repaint);

        private List<Process> ProcessesList = new List<Process>();
        private int Processes = 0;

        void AddNewTab()
        {
            AddProcessTab("webtab", null);
        }

        void AddSourceTab(string URL)
        {
            AddProcessTab("websource", URL);
        }

        void AddProcessTab(string CMD, string Args)
        {
            /*PictureBox pictureBox = new PictureBox();
            pictureBox.Dock = System.Windows.Forms.DockStyle.Fill;
            pictureBox.Image = global::FireWeb.Properties.Resources.attenzione;
            pictureBox.Location = new System.Drawing.Point(0, 0);
            pictureBox.Name = "pictureBox1";
            pictureBox.Size = new System.Drawing.Size(659, 358);
            pictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;
            pictureBox.TabIndex = 1;
            pictureBox.TabStop = false;*/

            TabPage Tab = new TabPage(LangManager.GetString("NewTab", Culture));
            Tab.Name = Processes.ToString();
            Tab.ImageKey = "default";
            Tab.BackColor = Color.White;
            //Tab.BackgroundImage = global::FireWeb.Properties.Resources.attenzione;
            Tab.BackgroundImageLayout = ImageLayout.Center;
            Tabs.TabPages.Add(Tab);

            Process WebThread = Process.Start("FireWeb", CMD + " " + Process.GetCurrentProcess().Id + " " + PipeName + " " + Processes + " " + Args);
            WebThread.WaitForInputIdle();
            Thread.Sleep(500);
            SetParent(WebThread.MainWindowHandle, Tab.Handle);
            //MessageBox.Show("W: " + Tab.Width + " H: " + Tab.Height);
            MoveWindow(WebThread.MainWindowHandle, 0, 0, Tab.Width, Tab.Height, false);

            ProcessesList.Insert(Processes, WebThread);
            Processes += 1;

            int i = Tabs.TabPages.Count - 1;
            Tabs.SelectedTab = Tabs.TabPages[i];
        }

        void ProcessResize()
        {
            try
            {
                TabPage Tab = Tabs.SelectedTab;
                Process WebThread = ProcessesList[int.Parse(Tab.Name)];
                MoveWindow(WebThread.MainWindowHandle, 0, 0, Tab.Width, Tab.Height, true);
            }
            catch { }
        }
        #endregion

        #region Server Voids
        void Server_ProcessPacket(byte[] message)
        {
            try
            {
                Invoke(new Pipe.Server.MessageReceivedHandler(ProcessPacket),
                    new object[] { message });
            }
            catch { }
        }

        void ProcessPacket(byte[] message)
        {
            ASCIIEncoding encoder = new ASCIIEncoding();
            string str = encoder.GetString(message, 0, message.Length);

            //ASCIIEncoding encoder = new ASCIIEncoding();
            //byte[] messageBuffer = encoder.GetBytes(tbSend.Text);
            //Server.SendMessage(messageBuffer);

            //MessageBox.Show(str);
            string[] CMD = str.Split(Convert.ToChar(1));
            switch (CMD[0])
            {
                case "newwebtab":
                    {
                        AddNewTab();
                        break;
                    }
                case "webtabprogress":
                    {
                        SetProgressTaskbar(int.Parse(CMD[1]));
                        break;
                    }
                case "tabtitle":
                    {
                        TabPage Tab = Tabs.TabPages[CMD[1]];
                        try
                        {
                            Tab.Text = CMD[2].Substring(0, 24) + "...";
                        }
                        catch { Tab.Text = CMD[2]; }

                        CompleteTitle.Insert(int.Parse(CMD[1]), CMD[2]);
                        break;
                    }
                case "tabmanager":
                    {
                        Pages.TabManager TabManager = new Pages.TabManager(Process.GetCurrentProcess().Id);
                        TabManager.Show();
                        break;
                    }
                case "websource":
                    {
                        AddSourceTab(CMD[1]);
                        break;
                    }
                case "favicon":
                    {
                        if (!FavIcons.Images.ContainsKey(CMD[2]))
                        {
                            Image tFavicon = Image.FromStream(System.Net.FileWebRequest.Create(CMD[2]).GetResponse().GetResponseStream());
                            FavIcons.Images.Add(CMD[2], tFavicon);
                        }

                        TabPage Tab = Tabs.TabPages[CMD[1]];
                        Tab.ImageKey = CMD[2];
                        break;
                    }
            }
        }

        void Server_ClientDisconnected()
        {
            try
            {
                Invoke(new Pipe.Server.ClientDisconnectedHandler(ClientDisconnected));
            }
            catch { }
        }

        void ClientDisconnected()
        {
            //MessageBox.Show("Total clients: " + Server.TotalConnectedClients);
            //label1.Text = "Schede: " + Server.TotalConnectedClients;
        }
        #endregion

        #region Form Events
        private void App_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (Server.TotalConnectedClients > 1)
            {
                DialogResult ClosingDialog = MessageBox.Show("Attenzione: più di una scheda è aperta, sei sicuro di voler chiudere tutte le schede?", "FireWeb", MessageBoxButtons.YesNo, MessageBoxIcon.Information);
                if (ClosingDialog == DialogResult.No)
                {
                    e.Cancel = true;
                }
            }
        }

        private void App_Resize(object sender, EventArgs e)
        {
            ProcessResize();
        }
        #endregion

        #region Windows 7 Voids
        void MakeThumbnail()
        {
            if (TaskbarManager.IsPlatformSupported)
            {
                
            }
        }

        void MakeJumpList()
        {
            if (TaskbarManager.IsPlatformSupported)
            {

            }
        }

        void SetProgressTaskbar(int Progress)
        {
            if (TaskbarManager.IsPlatformSupported)
            {
                windowsTaskbar.SetProgressState(TaskbarProgressBarState.Normal);
                windowsTaskbar.SetProgressValue(Progress, 100);
                if (Progress == 100)
                {
                    ProgressBarReset.Start();
                }
            }
        }

        private void ProgressBarReset_Tick(object sender, EventArgs e)
        {
            ProgressBarReset.Stop();
            windowsTaskbar.SetProgressState(TaskbarProgressBarState.NoProgress);
        }
        #endregion

        private void App_Paint(object sender, PaintEventArgs e)
        {
            /*if (DWM.DwmIsCompositionEnabled())
            {
                e.Graphics.FillRectangles(Brushes.Black, new Rectangle[] {
		            new Rectangle(0, 0, this.ClientSize.Width, 28),
		            new Rectangle(this.ClientSize.Width - 0, 0, 0, this.ClientSize.Height),
		            new Rectangle(0, this.ClientSize.Height - 0, this.ClientSize.Width, 0),
		            new Rectangle(0, 0, 0, this.ClientSize.Height)
	            });
            }*/
        }

        private void blockTabMenu_Click(object sender, EventArgs e)
        {
            TabPage Tab = Tabs.SelectedTab;
            Tab.Text = "";
        }

        private void UpdateTitle_Tick(object sender, EventArgs e)
        {
            try
            {
                TabPage Tab = Tabs.SelectedTab;
                this.Text = CompleteTitle[int.Parse(Tab.Name)];
            }
            catch 
            {
                try
                {
                    TabPage Tab = Tabs.SelectedTab;
                    this.Text = Tab.Text;
                }
                catch { }
            }
        }

        private void Tabs_SelectedIndexChanged(object sender, EventArgs e)
        {
            ProcessResize();
        }

        private void newTabMenu_Click(object sender, EventArgs e)
        {
            AddNewTab();
        }

        private void closeTabMenu_Click(object sender, EventArgs e)
        {
            Process Proc = ProcessesList[int.Parse(Tabs.SelectedTab.Name)];
            Proc.Kill();
            Tabs.TabPages.Remove(Tabs.SelectedTab);

            if (Tabs.TabCount < 1)
            {
                this.Close();
            }
        }

        private void App_Load(object sender, EventArgs e)
        {
            // New Tab
            AddNewTab();
            this.Refresh();
            FavIcons.Images.Add("default", Properties.Resources.favicon);
        }
    }
}
